package buco.integrity.typehierarchy;

import java.util.*;

import buco.core.api.*;

public class TypeHierarchyIntegrityCheck extends IntegrityCheck {
	
	@Override
	public void checkIntegrity(Bundle bundle, IntegrityReport report) { 
		List<IsSubClassOf> list = bundle.getSemanticConstraints("isSubClassOf", IsSubClassOf.class); 
		ArrayList<DefineInheritance> hierarchies = new ArrayList<DefineInheritance>(); 
		
		if(list.size() > 0) { 
			List<BundleWire> wires = composition.getOutgoingWires(bundle, true);
			for(BundleWire wire : wires) { 
				hierarchies.addAll(
						wire.getTo().getSemanticConstraints("isSubClassOf", DefineInheritance.class)
				);
			}
			
			for(IsSubClassOf sc : list) { 
				if(!checkInheritance(sc, hierarchies)) {
					report.warn(String.format("Possible Type missmatch: Class %s is not a sub-class of %s.",
							sc.getClassName(), 
							sc.getBaseClass()));
				}
			}
		}
	}
	
	private boolean checkInheritance(IsSubClassOf sc, List<DefineInheritance> list) { 
		for(DefineInheritance di : list) { 
			if(di.getClassGraph().isSubType(sc.getClassName(), sc.getBaseClass()))
				return true;
		}
		return false;
	}

}
